package com.adityayadav.parallelism.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.SortedSet;

public class TimedTaskScheduler {

	protected ArrayList<ScheduledTask> scheduledTasks = new ArrayList<ScheduledTask>(); 
	protected ThreadPool taskThreadPool;
	
	public TimedTaskScheduler(ThreadPool taskThreadPool){
		this.taskThreadPool = taskThreadPool;
		java.lang.Thread scheduler = new java.lang.Thread(){
			public void run(){
				while (true){
					if (!scheduledTasks.isEmpty()){
						long minimumTime = Long.MAX_VALUE;
						synchronized(TimedTaskScheduler.this){
							Iterator it = scheduledTasks.iterator();
							while (it.hasNext()){
								ScheduledTask scheduledTask = (ScheduledTask)it.next();
								if (scheduledTask.trigger < minimumTime) minimumTime = scheduledTask.trigger;
								if (scheduledTask.trigger < System.currentTimeMillis()){
									TimedTaskScheduler.this.taskThreadPool.addTask(scheduledTask.task);
									it.remove();
								}
							}                
						}
						long sleepDuration = minimumTime - System.currentTimeMillis();
						if (sleepDuration >0){
							try {
								Thread.sleep(sleepDuration);
							}catch (Exception e){}
						}

					}else {
						try {
							//synchronized(TimedTaskScheduler.this){
								TimedTaskScheduler.this.wait();
							//}
						} catch (Exception e){};
					}
				}
			}
		};
		scheduler.start();
	}
	
	public void addTask(ITask task, int milliseconds){
		synchronized(TimedTaskScheduler.this){
			ScheduledTask scheduledTask = new ScheduledTask();
			scheduledTask.trigger = System.currentTimeMillis()+milliseconds;
			//System.out.println("Current: "+System.currentTimeMillis());
			//System.out.println("Trigger: "+scheduledTask.trigger);
			scheduledTask.task = task;
			scheduledTasks.add(scheduledTask);
			if (scheduledTasks.size() == 1) {
				TimedTaskScheduler.this.notify();
			}
		}
		
	}
	
	public boolean isIdle(){
		return scheduledTasks.isEmpty();
	}
	
	public class ScheduledTask{
		public ITask task;
		public long trigger;
	}
}
